import * as THREE from 'three'
import { v4 as uuidv4 } from 'uuid'
import { ref } from 'vue'

export type GeometryType = 'box' | 'sphere' | 'cylinder'

export type Operation = 'create' | 'update' | 'delete'

export interface GeometryItem {
  id: string
  type: GeometryType
  mesh: THREE.Mesh
  name: string
}

const createId = () => {
  const id = uuidv4()
  return id
}

const addLine = (mesh: THREE.Mesh) => {
  const edgeGeometry = mesh.geometry
  const edges = new THREE.EdgesGeometry(edgeGeometry)
  const lineMaterial = new THREE.LineBasicMaterial({
    color: 0x000000, // 边线颜色
    linewidth: 5, // 线宽（需要启用抗锯齿才有效）
    opacity: 0.5,
    transparent: true,
    depthWrite: true,
    depthTest: false,
  })
  const wireframe = new THREE.LineSegments(edges, lineMaterial)
  wireframe.renderOrder = 1
  mesh.add(wireframe) // 将线框附加到立方体上

  setLayer(mesh, 1)
}

const setLayer = (mesh: THREE.Mesh, layer: number) => {
  mesh.layers.set(layer)
  if (mesh.children.length > 0) {
    mesh.children.forEach((item) => {
      setLayer(item as THREE.Mesh, layer)
    })
  }
}

export function useLabel() {
  const geometries = ref<GeometryItem[]>([])

  function addBox(
    name: string,
    id: string = createId(),
    position: {
      x: number
      y: number
      z: number
    },
    x = 1,
    y = 1,
    z = 1,
  ) {
    const geometry = new THREE.BoxGeometry(1, 1, 1)
    const material = new THREE.MeshBasicMaterial({
      color: 0x00ff00,
      opacity: 0.5, // 透明度 0-1
      transparent: true, // 透明材质
    })
    const mesh = new THREE.Mesh(geometry, material)
    mesh.scale.set(x, y, z)
    mesh.position.copy(position)
    const item: {
      id: string
      type: GeometryType
      name: string
      mesh: THREE.Mesh
    } = { id, type: 'box', mesh, name }
    geometries.value.push(item)
    // mesh.layers.set(1) // 设置网格的层级

    addLine(item.mesh)
    return item
  }

  function addSphere(
    name: string,
    id: string = createId(),
    position: {
      x: number
      y: number
      z: number
    },
    x = 1,
    y = 1,
    z = 1,
  ) {
    const geometry = new THREE.SphereGeometry(1, 28, 10)
    const material = new THREE.MeshBasicMaterial({
      color: 0xff0000,
      opacity: 0.5, // 透明度 0-1
      transparent: true, // 透明材质
      depthWrite: true,
      depthTest: false,
    })
    const mesh = new THREE.Mesh(geometry, material)
    mesh.position.copy(position)
    mesh.scale.set(x, y, z)
    const item: {
      id: string
      type: GeometryType
      mesh: THREE.Mesh
      name: string
    } = { id, type: 'sphere', mesh, name }
    geometries.value.push(item)
    // mesh.layers.set(1) // 设置网格的层级

    addLine(item.mesh)
    return item
  }

  function addCylinder(
    name: string,
    id: string = createId(),
    position: {
      x: number
      y: number
      z: number
    },
    x: number = 1,
    y: number = 1,
    z: number = 1,
  ) {
    const geometry = new THREE.CylinderGeometry(1, 1, 1, 32)
    const material = new THREE.MeshBasicMaterial({
      color: 0x0000ff,
      opacity: 0.5, // 透明度 0-1
      transparent: true, // 透明材质
      depthWrite: true,
      depthTest: false,
    })
    const mesh = new THREE.Mesh(geometry, material)
    mesh.scale.set(x, y, z)
    mesh.position.copy(position)
    const item: {
      id: string
      type: GeometryType
      mesh: THREE.Mesh
      name: string
    } = { id, type: 'cylinder', mesh, name }
    geometries.value.push(item)

    addLine(item.mesh)
    return item
  }

  function removeGeometry(id: string) {
    const index = geometries.value.findIndex((item) => item.id === id)
    if (index !== -1) {
      const [removed] = geometries.value.splice(index, 1)
      removed.mesh.geometry.dispose()
      const line = removed.mesh.children.find(
        (e) => (e as THREE.LineSegments).type === 'LineSegments',
      ) as THREE.LineSegments
      if (removed.mesh.material instanceof THREE.Material) {
        removed.mesh.material.dispose()
      }
      line && line.geometry.dispose()
      if (line) {
        if (Array.isArray(line.material)) {
          line.material.forEach((mat) => mat.dispose())
        } else {
          line.material.dispose()
        }
      }
      removed.mesh.removeFromParent()
    }
  }

  function clearAll() {
    geometries.value.forEach((item) => {
      item.mesh.geometry.dispose()
      if (item.mesh.material instanceof THREE.Material) {
        item.mesh.material.dispose()
      }
    })
    geometries.value = []
  }

  function checkGeometry(id: string) {
    geometries.value.forEach((item) => {
      setLayer(item.mesh, 1)
      const line = item.mesh.children.find(
        (e) => (e as THREE.LineSegments).type === 'LineSegments',
      )
      if (line && line instanceof THREE.LineSegments) {
        ;(line.material as THREE.LineBasicMaterial).color.set(0x000000)
        line.renderOrder = 1
      }
    })
    const item = geometries.value.find((item) => item.id === id)
    if (!item) return
    const line = item.mesh.children.find(
      (e) => (e as THREE.LineSegments).type === 'LineSegments',
    )
    if (line && line instanceof THREE.LineSegments) {
      ;(line.material as THREE.LineBasicMaterial).color.set(0xf5982e)
    }

    if (line) {
      line.renderOrder = 9999
    }
    setLayer(item.mesh, 2)
    // const geometry = item.mesh.geometry
    // const edges = new THREE.EdgesGeometry(geometry)
    // const lineMaterial = new THREE.LineBasicMaterial({
    //   color: 0xf5982e, // 边线颜色
    //   linewidth: 5, // 线宽（需要启用抗锯齿才有效）
    //   // depthWrite: false,
    //   // depthTest: false, // 关闭深度测试
    // })
    // const wireframe = new THREE.LineSegments(edges, lineMaterial)
    // wireframe.renderOrder = 1
    // item.mesh.add(wireframe) // 将线框附加到立方体上
    // item.mesh.layers.set(2)
    // wireframe.layers.set(2) // 设置线框的层级
  }

  return {
    geometries,
    addBox,
    addSphere,
    addCylinder,
    removeGeometry,
    clearAll,
    checkGeometry,
  }
}
